<template>
  <div class="remote-select-wrapper">
    <a-select
      v-model="selectValue"
      v-model:popup-visible="popupVisible"
      :allow-clear="allowClear"
      :loading="fetching"
      :filter-option="false"
      :fallback-option="fallback"
      :show-extra-options="false"
      :trigger-props="{ updateAtScroll }"
      placeholder="请选择"
      allow-search
      popup-container=".remote-select-wrapper"
      multiple
      show-header-on-empty
      v-bind="$attrs"
      @popup-visible-change="popupVisibleChange"
      @search="fetchListApi"
      @change="handleChangeFn"
      @blur="handleBlurFn"
      @focus="handleFocusFn"
    >
      <!-- 全部选择 -->
      <template #header v-if="mustParentShow == false && allShow">
        <div style="padding: 6px 12px">
          <a-checkbox v-model="checkboxValue" @change="allChange">{{ allLabel }}</a-checkbox>
        </div>
      </template>
      <template #label="{ data }">
        <slot name="label" :data="data">
          {{ selector.labelFn ? selector.labelFn(selectedOption) : data.label }}
        </slot>
      </template>
      <template #empty>
        <!-- 请选择上级 -->
        <a-alert v-if="mustParentShow" type="warning">
          <template #icon>
            <icon-exclamation-circle />
          </template>
          {{ mustParentTip }}
        </a-alert>
        <div v-else-if="allShow" style="height: 4px"></div>
      </template>
      <a-option
        v-for="(item, optionIndex) in options"
        :key="item[selector.key]"
        :value="item[selector.key]?.toString()"
        :label="item[selector.label]"
        :disabled="item.disabled"
      >
        <slot name="option" :option="item" :index="optionIndex">
          <template v-if="selector.tag">
            <!-- 员工状态 -->
            <!-- 在职：1（blue）停用：2（gray） 离职：0（orange） -->
            <a-tag
              v-if="selector.tag == 'staff'"
              :color="item.status == 1 ? 'blue' : item.status == 2 ? 'gray' : 'orange'"
              class="staff-status"
              size="small"
              >{{ item.statusName }}</a-tag
            >
          </template>
          {{ selector.optionFn ? selector.optionFn(item) : item[selector.label] }}
        </slot>
      </a-option>
    </a-select>
  </div>
</template>

<script setup name="RemoteMultipleSelect">
  import { ref, watch, readonly, nextTick, computed, onMounted } from 'vue'
  import { useVModel } from '@vueuse/core'

  const props = defineProps({
    modelValue: Array,
    type: {
      type: String,
      require: true,
    },
    selector: Object,
    initStr: String,
    // 接口参数
    params: {
      type: Object,
      default: () => {},
    },
    allowClear: {
      type: Boolean,
      default: () => true,
    },
    // 滚动容易导致下拉菜单分离
    updateAtScroll: {
      type: Boolean,
      default: () => false,
    },
    // 滚动关闭下拉菜单
    scrollToClose: {
      type: Boolean,
      default: () => false,
    },
    // 级联相关
    mustParentShow: Boolean,
    mustParentTip: {
      type: String,
      default: () => '请先选择上级',
    },
    hookChange: Object,
    // 全选相关
    allShow: Boolean,
    allValue: Boolean,
    allLabel: {
      type: String,
      default: '全部',
    },
    fallbackOption: Object,
    // 默认是否加载数据，优先lazyloading
    mountedLoad: {
      type: Boolean,
      default: true,
    },
    // 延迟加载，默认不加载blur时候加载
    lazyloading: {
      type: Boolean,
      default: () => false,
    },
  })

  const emit = defineEmits([
    'update:modelValue',
    'focus',
    'blur',
    'change',
    'visibleChange', // 2025-03-25新增，防止重复掉接口
    'update:allValue',
    'clearValue',
    'optionsList',
  ])

  const selectValue = useVModel(props, 'modelValue', emit)
  const checkboxValue = useVModel(props, 'allValue', emit)
  const selector = readonly(props.selector)
  const options = ref([])
  const keyword = ref('')
  const lastFetchId = ref(0)
  const fetching = ref(false)
  const popupVisible = ref(false)

  // 当前选中的选项
  const selectedOption = computed(() => {
    if (options.value && options.value.length) {
      const current = options.value.find((item) => item[selector.key || 'id'] == props.modelValue)
      return current || {}
    } else {
      return {}
    }
  })

  // 全部选择change
  const allChange = (val) => {
    selectValue.value = undefined
    if (val) {
      popupVisible.value = false
      selectValue.value = ['all']
    }
    emit('update:allValue', val)
    nextTick(() => {
      fetchListApi()
    })
  }

  const fallback = (value) => {
    if (props.fallbackOption) return props.fallbackOption
    if (value != 'all') return
    return {
      value,
      label: `全部车辆`,
    }
  }

  // change 事件
  let record_options = []
  const handleChangeFn = (value) => {
    if (!value || value.length == 0) {
      allChange(false)
      checkboxValue.value = false
    }

    record_options = options.value
    emit('change', value, record_options)
    props.hookChange.change()
    if (popupVisibleValue == false) {
      emit('visibleChange', value, record_options)
    }
  }
  // 接口调用
  const fetchListApi = async (value) => {
    if (props.mustParentShow == true || props.allValue == true) {
      options.value = []
      return
    }

    fetching.value = true
    lastFetchId.value += 1
    const fetchId = lastFetchId.value
    const queryParam = {
      ...selector.data,
      ...props.params,
    }
    // 增加关键字参数
    keyword.value = value
    queryParam[selector.keyword] = value

    const res = await selector.api(queryParam)
    fetching.value = false
    if (res.code == 200) {
      if (fetchId !== lastFetchId.value) {
        // 非顺序
        return
      }
      const result = res.result || [] // 可能为null
      // 兼容
      if (result.data) {
        options.value = result.data
      } else {
        options.value = result
      }
      emit('optionsList', options.value)
    }
  }

  const staticParams = computed(() => {
    return JSON.stringify(props.params)
  })
  watch(
    () => staticParams.value,
    () => {
      fetchListApi()
    }
  )
  onMounted(() => {
    if (props.mountedLoad == false) return
    if (props.lazyloading == true) return
    fetchListApi()
  })

  // 打开时 拿无关键字列表
  let oldValue = ''
  let popupVisibleValue = false
  const popupVisibleChange = (visible) => {
    popupVisibleValue = visible
    if (visible == true) {
      if (keyword.value || props.lazyloading == true) {
        fetchListApi()
      }
      oldValue = selectValue.value + ''
    } else {
      let newValue = selectValue.value + ''
      if (oldValue != newValue) {
        emit('visibleChange', selectValue.value || [], record_options)
      }
    }
  }

  // 获取焦点
  const handleFocusFn = () => {
    emit('focus')
  }
  // 失去焦点
  const handleBlurFn = () => {
    emit('blur')
  }
</script>

<style lang="less" scoped>
  .remote-select-wrapper {
    width: 100%;
    position: relative;
  }
  .staff-status {
    padding: 0 3px;
  }
</style>
